package cate.game.role.friend.aid;

import cate.common.table.d.GDFriendAid;
import cate.common.table.d.GDFunc;
import cate.common.table.d.GDMail;
import cate.common.util.GameResult;
import cate.game.framework.ThreadShare;
import cate.game.friend.aid.ServerRoleAidHero;
import cate.game.mail.po.MailBuilder;
import cate.game.res.MixResAdder;
import cate.game.role.Role;
import cate.game.role.RoleDependent;
import cate.game.role.bag.hero.Hero;
import cate.game.role.friend.aid.msg.FriendAidBorrowResp;
import cate.game.role.friend.aid.msg.FriendAidListResp;
import cate.game.role.friend.aid.msg.FriendAidProvideResp;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.Lists;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@NoteClass("我的借用数据")
public class FriendAid extends RoleDependent {
    @NoteField("我借来的食灵数据 <功能ID， 援助食灵数据>")
    private Map<Integer, List<Hero>> items;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (items == null) {
            items = new HashMap<>();
        }
    }

    @JsonIgnore
    public void getAidList(int funcId, Set<String> friendUids) {
        List<ServerRoleAidHero> aidList = role.getGame().friendAid.getAidHeros(funcId, friendUids);
        ServerRoleAidHero provideHero = role.getGame().friendAid.getProvideHero(role.getUid(), funcId);
        role.sendNow(new FriendAidListResp(funcId, aidList
                , items.get(funcId) != null ? items.get(funcId).stream().map(e -> e.uid).collect(Collectors.toList()) : Collections.emptyList()
                , provideHero != null ? provideHero.heros.stream().map(e -> e.uid).collect(Collectors.toList()) : Collections.emptyList()));
    }

    public GameResult<Void> borrow(int funcId, String roleUid, String heroUid) {
        GameResult<Void> r = new GameResult<>();
        ServerRoleAidHero aidHero = role.getGame().friendAid.borrow(roleUid, funcId);
        if (aidHero == null || !aidHero.containsHero(heroUid)) {
            return r.fail("不存在的英雄");
        }
        GDFriendAid.FuncAidData aidData = GDFriendAid.getAidData(funcId);
        int limit = aidData.getBorrowTimes();
        List<Hero> heros = items.computeIfAbsent(funcId, k -> new ArrayList<>());
        if (heros.size() >= limit) {
            return r.fail("每天只可雇佣" + limit + "次");
        }
        if (heros.stream().anyMatch(e -> StringUtils.equals(e.uid, heroUid))) {
            return r.fail("您已经雇佣了这只英雄");
        }
        Hero hero = aidHero.findHero(heroUid).copy();
        hero.initialize(null);
        if (hero.getPower(role.getGame().fight.getPlayBuildContext()) > aidData.getAidPowerLimit() * role.getRes().worldTree.heroShare.heroPowerMax) {
            return r.fail("该英雄战力超出限制，不可选择");
        }
        heros.add(hero);
        role.sendNow(new FriendAidBorrowResp(funcId, roleUid, heroUid));

        if (aidHero.successAid() < aidData.getBorrowRewardTimes()) {
            Role friend = role.getGame().role.getRole(roleUid);
            if (friend != null) {
                ThreadShare.instance().exe(friend, () ->
                        friend.getMail().add(new MailBuilder().
                                setRewardConf(aidData.getBorrowReward()).
                                setContentId(GDMail.Tid.ENDLESS_FRIEND_AID).
                                setParamList(Lists.newArrayList(role.getBase().name)).
                                build()));
            }
        }
        return r;
    }

    public GameResult<Void> provide(int funcId, Hero hero) {
        GameResult<Void> r = role.getGame().friendAid.provide(role, funcId, hero);
        if (r.ok()) {
            GDFriendAid.FuncAidData aidData = GDFriendAid.getAidData(funcId);
            new MixResAdder()
                    .setRes(aidData.getAidReward())
                    .setDialogReward(true)
                    .setSendMailWhenFull(true)
                    .exe(role);
            role.sendNow(new FriendAidProvideResp(funcId, hero.uid));
            if (funcId == GDFunc.ENDLESS) {
                role.getHistory().action.endlessAidTimes();
            }
        }
        return r;
    }

    public Hero findAidHero(int funcId, String heroUid) {
        List<Hero> aidHero = items.get(funcId);
        if (aidHero != null) {
            return aidHero.stream().filter(e -> StringUtils.equals(e.uid, heroUid)).findAny().orElse(null);
        }
        return null;
    }

    @Override
    public void onDaySpan(boolean silence) {
        items.clear();
    }
}
